package com.example.gsp.mybatis.session;

import com.example.gsp.dao.SwitchDao;
import com.example.gsp.mybatis.config.Configuration;
import com.example.gsp.mybatis.config.MappedStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 加载配置信息到内存
 * 生成sqlSession
 */
public class SqlSessionFactory {

    private Configuration conf;

    private static final String DB_CONFIG_FILE = "jdbc.properties";
    private static final String MAPPER_CONFIG_LOCATION = "mapper";

    public Configuration getConf() {
        return conf;
    }

    public void setConf(Configuration conf) {
        this.conf = conf;
    }

    public SqlSessionFactory() {
        conf = new Configuration();
        loadDbInfo();
        loadMappersInfo();
    }

    private void loadDbInfo() {
        InputStream dbIn = SqlSessionFactory.class.getClassLoader().getResourceAsStream(DB_CONFIG_FILE);
        Properties properties = new Properties();
        try {
            properties.load(dbIn);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!properties.isEmpty()) {
            conf.setDriver(properties.getProperty("jdbc_driverClassName"));
            conf.setUrl(properties.getProperty("jdbc_url"));
            conf.setUsername(properties.getProperty("jdbc_username"));
            conf.setPassword(properties.getProperty("jdbc_password"));
        }
    }

    private void loadMappersInfo() {
        URL resource = SqlSessionFactory.class.getClassLoader().getResource(MAPPER_CONFIG_LOCATION);
        File mappers = new File(resource.getFile());
        if (mappers.isDirectory()) {
            Arrays.stream(mappers.listFiles()).filter((file -> file.getName().endsWith("Mapper.xml"))).forEach((file) -> loadMapperInfo(file));
        }

    }

    private void loadMapperInfo(File file) {
        SAXReader reader = new SAXReader();
        Document document = null;
        try {
            document = reader.read(file);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        Element root = document.getRootElement();
        String namespace = root.attributeValue("namespace");
        List<Element> selects = root.elements("select");
        for (Element element : selects) {
            MappedStatement statement = new MappedStatement();
            String id = namespace + "." + element.attributeValue("id");
            String resultType = element.attributeValue("resultType");
            String sql = element.getText();
            statement.setNamespace(namespace);
            statement.setResultType(resultType);
            statement.setSourceId(id);
            statement.setSql(sql);
            conf.getMappedStatementMap().put(id, statement);
        }
    }

    public SqlSessionFactory(Configuration conf) {
        this.conf = conf;
    }

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactory();
        SqlSession sqlSession = new DefaultSqlSession(sqlSessionFactory.conf);
        SwitchDao switchDao = sqlSession.getMapper(SwitchDao.class);
        System.out.println(switchDao.selectSwitchMap());
    }
}
